﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using Brouteforce.gameObjs;
//using Brouteforce.gameObjs.gamePiece;
//using Brouteforce.gameobjs;
//using Brouteforce.util;
//using Brouteforce.utilities;
//using Microsoft.Xna.Framework;
//using Microsoft.Xna.Framework.Graphics;

//namespace Brouteforce.managers {
//    public static class WorldManager {
//        #region Constants

//        public const double TilesX = 50;
//        public const double TilesY = 50;
//        public const int TileW = 32;
//        public const int TileH = 32;

        
//        public static readonly Rectangle WorldRect = new Rectangle(0, 0, (int)(TilesX * TileW), (int)(TilesY * TileH));

//        #endregion

//        #region Fields

//        public static Tile[,] World;
//        private static Camera Camera;
//        public static List<Vector2> HighlightBackUp = new List<Vector2>();
//        private static GamePiece _curHighlightedGamePiece = null;
//        private static State? _curHighlightType = null;
//        #endregion

//        #region Output


//        public static Tile TileUnderMouse {
//            get {
//                var tx = Math.Floor((double)((Camera.ViewingLocation.OnScreenX + InputManager.CurMouseX) / TileW));
//                var ty = Math.Floor((double)((Camera.ViewingLocation.OnScreenY + InputManager.CurMouseY) / TileH));
//                if (tx >= 0 && tx <= TilesX && ty >= 0 && ty <= TilesY)
//                    return World[(int)tx, (int)ty];
//                return null;
//            }
//        }

//        public static Tower[] InitialGameTowers;

//        #endregion

//        #region Game Loop
//        public static void Initialize() {
//            World = new Tile[(int)TilesX, (int)TilesY];
//            for (int i = 0; i < TilesX; i++)
//                for (int j = 0; j < TilesY; j++)
//                    World[i, j] = new Tile(new Rectangle(i * TileW, j * TileH, TileW, TileH), i, j);

//            var screenBounds = BFGame.Graphics.GraphicsDevice.Viewport.Bounds;
//            var cameraSize = new Rectangle(0, 0, screenBounds.Width, screenBounds.Height - DashboardManager.DashboardHeight);

//            Camera = new Camera(cameraSize);
//        }

//        public static void Update(){
//            UpdateWorld();
//            Camera.Update();
//            UpdateHighlighting();
//        }

//        private static void UpdateWorld(){
//            if (GameManager.IsNewGameStarted){
//                GenerateRandomWorld();
//            }
//        }

//        public static void Draw() {
//            Camera.Draw();
//        }

//        #endregion

//        #region Highlighting

//        /// <summary>
//        /// HighlightWalkRange a zone
//        /// </summary>
//        /// <param name="tileX">the center tile x parameter</param>
//        /// <param name="tileY">the center tile y parameter</param>
//        /// <param name="color">the color to highligh to</param>
//        /// <param name="radius">the highlight radius</param>
//        private static void HighlightWalkRange(int tileX, int tileY, Color color, int radius) {
//            HighlightBackUp.Clear();

//            int xStart = tileX - radius;
//            int xEnd = tileX + radius;
//            int yStart = tileY - radius;
//            int yEnd = tileY + radius;

//            for (int i = xStart, j = 0; i < xEnd; i++, j++) {
//                if ((i < 0) || (i >= World.GetLength(0)))
//                    continue;
//                Vector2 iTile = new Vector2(i, tileY);
//                if ((!(Tiles.FindPath(new Vector2(tileX, tileY), iTile, radius).Count > radius + 1)) &&
//                    ((WorldManager.GetTileAt(iTile).ContainedGamePieces.Count == 0) || (!WorldManager.GetTileAt(iTile).ContainOtherThan(typeof(Tower))))) {
//                    HighlightBackUp.Add(iTile);
//                    World[i, tileY].Highlight(color);
//                }
//                for (int k = 1; k <= j; k++) {
//                    Vector2 j1Tile = new Vector2(i, tileY - k);
//                    Vector2 j2Tile = new Vector2(i, tileY + k);
//                    if ((!(tileY - k < 0)) && (!(Tiles.FindPath(new Vector2(tileX, tileY), j1Tile, radius).Count > radius + 1)) &&
//                        ((WorldManager.GetTileAt(j1Tile).ContainedGamePieces.Count == 0) || (!WorldManager.GetTileAt(j1Tile).ContainOtherThan(typeof(Tower))))) {
//                        HighlightBackUp.Add(j1Tile);
//                        World[i, tileY - k].Highlight(color);
//                    }
//                    if ((!(tileY + k >= World.GetLength(1))) && (!(Tiles.FindPath(new Vector2(tileX, tileY), j2Tile, radius).Count > radius + 1)) &&
//                        ((WorldManager.GetTileAt(j2Tile).ContainedGamePieces.Count == 0) || (!WorldManager.GetTileAt(j2Tile).ContainOtherThan(typeof(Tower))))) {
//                        HighlightBackUp.Add(j2Tile);
//                        World[i, tileY + k].Highlight(color);
//                    }
//                    if (k >= radius - Math.Abs(tileX - i))
//                        break;
//                }
//            }
//            Vector2 lastTile = new Vector2(xEnd, tileY);
//            if ((!(xEnd >= World.GetLength(0))) && (!(Tiles.FindPath(new Vector2(tileX, tileY), lastTile, radius).Count > radius + 1)) && 
//                ((WorldManager.GetTileAt(lastTile).ContainedGamePieces.Count == 0 ) || (!WorldManager.GetTileAt(lastTile).ContainOtherThan(typeof(Tower))))) {
//                HighlightBackUp.Add(lastTile);
//                World[xEnd, tileY].Highlight(color);
//            }
//        }


//        /// <summary>
//        /// remove the last highlighting
//        /// </summary>
//        private static void Lowlight() {
//            foreach (Vector2 v in HighlightBackUp) {
//                World[(int)v.X, (int)v.Y].Lowlight();
//            }
//            HighlightBackUp.Clear();
//        }


//        private static void UpdateHighlighting() {
//            if (PlayersManager.SelectedGamePiece == null && _curHighlightedGamePiece != null) {
//                _curHighlightedGamePiece = null;
//                Lowlight();
//            } else if (PlayersManager.SelectedGamePiece != null) {
//                if (PlayersManager.SelectedGamePiece != _curHighlightedGamePiece ||
//                    PlayersManager.InputState != _curHighlightType) {
//                    Lowlight();
//                    _curHighlightedGamePiece = PlayersManager.SelectedGamePiece;
//                    _curHighlightType = PlayersManager.InputState;

//                    Tile where = GetGamePieceTileInWorld(_curHighlightedGamePiece);
//                    if (where == null){
//                        Lowlight();
//                        return;
//                    }

//                    switch (_curHighlightType) {
//                        case State.Walking:
//                            HighlightWalkRange(where, Color.LightGreen, _curHighlightedGamePiece.NumberOfMovesLeft);
//                            break;

//                        case State.Firing:
//                            HighlightFireRange(where.XIndex, where.YIndex, Color.LightCoral, _curHighlightedGamePiece.Light);
//                            break;
//                    }
//                }
//            }
//        }

//        private static void HighlightWalkRange(Tile tilePos, Color color, int radius) {
//            HighlightWalkRange(tilePos.XIndex, tilePos.YIndex, color, radius);
//        }

//        private static void HighlightFireRange(int tileX, int tileY, Color color, int radius) {
//            Lowlight();

//            var tx1 = (int)Math.Min(Math.Max(0, tileX - radius), TilesX - 1);
//            var ty1 = (int)Math.Min(Math.Max(0, tileY - radius), TilesY - 1);

//            var tx2 = (int)Math.Min(Math.Max(0, tileX + radius), TilesX - 1);
//            var ty2 = (int)Math.Min(Math.Max(0, tileY + radius), TilesY - 1);

//            List<GamePiece> piecesWithinRange = GetAllGamePiecesInTileRange(tx1, ty1, tx2, ty2);
//            World[tileX, tileY].ContainedGamePieces.ForEach(p => piecesWithinRange.Remove(p));
//            var obstacles = piecesWithinRange.Select(gc => gc.Location.Shrink(1).Position).ToList();

//            for (int i = tx1; i <= tx2; i++) {
//                for (int j = ty1; j <= ty2; j++) {
//                    if (i == tileX && j == tileY)
//                        continue;

//                    Vector4 lineOfSight = Geometrics.CentersLine(World[tileX, tileY].Sprite.Location.Position,
//                                                                 World[i, j].Sprite.Location.Position);
//                    if (!obstacles.Any(p => World[i, j].Sprite.Location.Shrink(1).Position != p && Geometrics.IsRectIntersectLineSegment(lineOfSight, p))) {
//                        World[i, j].Highlight(color);
//                        HighlightBackUp.Add(new Vector2(i, j));
//                    }
//                }
//            }
//        }

//        #endregion

//        private static List<GamePiece> GetAllGamePiecesInTileRange(int tx1, int ty1, int tx2, int ty2) {
//            var ret = new List<GamePiece>();
//            for (int i = tx1; i <= tx2; i++) {
//                for (int j = ty1; j < ty2; j++) {
//                    ret.AddRange(World[i, j].ContainedGamePieces);
//                }
//            }

//            return ret;
//        }

//        public static Tile GetTileAtCameraPosition(int x, int y) {
//            return WorldManager.GetTileAt(Camera.GetTileAtScreenPosition(x, y));
//        }


//        /// <summary>
//        /// Returns all the game pieces located in the desired location
//        /// </summary>
//        /// <param name="tilePos"> </param>
//        /// <returns></returns>

//        public static List<GamePiece> GetAllGamePiecesInTile(Vector2 tilePos) {
//            return GetTileAt(tilePos).ContainedGamePieces;
//        }

//        /// <summary>
//        /// Returns the tile in which the game piece is located
//        /// </summary>
//        /// <param name="gamePiece"></param>
//        /// <returns></returns>
//        public static Vector2 GetGamePieceTile(GamePiece gamePiece) {
//            var tileX = Math.Floor((double)(gamePiece.Location.OnScreenX / TileW));
//            var tileY = Math.Floor((double)(gamePiece.Location.OnScreenY / TileH));
//            return new Vector2((float)tileX, (float)tileY);
//        }

//        /// <summary>
//        /// Updates the Board that the piece have moved.
//        /// </summary>
//        /// <param name="gamePiece"></param>
//        /// <param name="Tile"></param>
//        public static void MoveGamePieceTo(GamePiece gamePiece, Vector2 tileFrom, Vector2 tileTo) {
//            GetTileAt(tileFrom).ContainedGamePieces.Remove(gamePiece);
//            GetTileAt(tileTo).ContainedGamePieces.Add(gamePiece);
//        }

//        /// <summary>
//        /// return the tile that is located on x,y - while x,y are NOT screen position but tile position
//        /// - means it is not in pixels...
//        /// </summary>
//        /// <param name="x"></param>
//        /// <param name="y"></param>
//        /// <returns></returns>
//        public static Tile GetTileAt(int x, int y) {
//            return World[x, y];
//        }

//        public static Tile GetTileAt(Vector2 pos) {
//            return World[(int)pos.X, (int)pos.Y];
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="t"></param>
//        /// <returns></returns>
//        public static Vector2 GetPosInWorld(Tile t) {
//            int tileX = (int)Math.Floor((double)(t.Sprite.Location.OnScreenX / TileW));
//            int tileY = (int)Math.Floor((double)(t.Sprite.Location.OnScreenY / TileH));
//            return new Vector2(tileX, tileY);
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        public static void GenerateRandomWorld() {

//            for (int i = 0; i < GameManager.NumberOfTowersInWorld - 2; i++) {
//                while (true) {
//                    var tile = GetTileAt(Randoms.Between(0, (int)TilesX), Randoms.Between(0, (int)TilesY));
//                    if (tile.Contain(typeof(GamePiece)))
//                        continue;

//                    if ((tile.XIndex == 0 && tile.YIndex == 0) || (tile.XIndex == TilesX-1 && tile.YIndex == TilesY-1)){
//                        continue; // this is the place for the players initial towers
//                    }

//                    tile.ContainedGamePieces.Add(Tower.GenerateRandomTower(tile, 0, 2));

//                    break;
//                }
//            }

//            //now we will put two towers on the edges of the map - left and right edges
//            var p0Tower = new Tower(1, 1, 1, 1, World[0, 0]){BelongsToPlayer = 0};
//            World[0,0].ContainedGamePieces.Add(p0Tower);

//            var p1Tower = new Tower(1, 1, 1, 1, World[(int) (TilesX - 1), (int) (TilesY - 1)]){BelongsToPlayer = 1};
//            World[(int) (TilesX-1), (int) (TilesY-1)].ContainedGamePieces.Add(p1Tower);

//            InitialGameTowers = new Tower[]{p0Tower, p1Tower};
//        }


//        /// <summary>
//        /// Adds and sets a game piece on the tile that is located on x,y - while x,y are NOT screen position but tile position
//        /// - means it is not in pixels...
//        /// </summary>
//        /// <param name="x"></param>
//        /// <param name="y"></param>
//        /// <param name="gamePiece"></param>
//        /// <param name="tile"> </param>
//        /// <returns></returns>
//        public static void SetGamePieceAtTile(GamePiece gamePiece, Vector2 tile) {
//            GetTileAt(tile).ContainedGamePieces.Add(gamePiece);
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="gamePiece"></param>
//        public static void RemoveGamePiece(GamePiece gamePiece) {
//            GetGamePieceTileInWorld(gamePiece).ContainedGamePieces.Remove(gamePiece);
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="tile"></param>
//        /// <returns></returns>
//        public static GamePiece GetOpponentGamePieceFromTile(Tile tile) {
//            List<GamePiece> gamePieces = GetAllGamePiecesInTile(new Vector2(tile.XIndex, tile.YIndex));
//            var all = gamePieces.FindAll(e => !(e is Tower));
//            return all.Count == 0 ? null : all[0];
//        }

//        /// <summary>
//        /// 
//        /// </summary>
//        /// <param name="gamePiece"></param>
//        /// <returns></returns>
//        public static Tile GetGamePieceTileInWorld(GamePiece gamePiece) {
//            foreach (Tile t in World) {
//                if (t.ContainedGamePieces.Any(x => x == gamePiece))
//                    return t;
//            }

//            return null;
//        }
//    }

//}
